package org.dawfinn.droiditarian;

import java.io.IOException;
import java.util.List;
import java.util.Locale;

import org.dawfinn.droiditarian.data.DeedLocation;
import org.dawfinn.droiditarian.view.MapItemView;

import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
import android.location.Address;
import android.location.Geocoder;
import android.os.AsyncTask;
import android.util.Log;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.ItemizedOverlay;
import com.google.android.maps.MapView;
import com.google.android.maps.OverlayItem;

/**
 * Adds deed locations to the map.
 */
public class MapOverlay extends ItemizedOverlay<OverlayItem> {

	private final List<DeedLocation> locations;
	private final Context context;
	private AlertDialog.Builder popup;

	public MapOverlay(Drawable defaultMarker, Context context, List<DeedLocation> locations) {
		super(defaultMarker);
		super.boundCenter(defaultMarker);
		this.context = context;
		this.locations = locations;
		populate();
	}

	@Override
	public void draw(Canvas canvas, MapView mapView, boolean shadow) {
		super.draw(canvas, mapView, false);
	}

	@Override
	protected OverlayItem createItem(int i) {
		DeedLocation loc = locations.get(i);
		GeoPoint point = new GeoPoint((int) (loc.getLatitude() * 1E6), (int) (loc.getLongitude() * 1E6));
		return new OverlayItem(point, i + "", "");
	}

	@Override
	public int size() {
		return locations.size();
	}

	@Override
	protected boolean onTap(int index) {
		initPopup();
		DeedLocation location = locations.get(index);
		if (location.getLocality() == null) {
			Log.i("MapOverlay", "Looking up city online");
			new GetCityAsyncTask().execute(location);
		} else {
			Log.i("MapOverlay", "City received from server");
			showPopup(location, formatCity(context.getString(R.string.good_deeds_title), location.getLocality(), location.getCountry()));
		}
		return true;
	}
	
	private void initPopup() {
		popup = new AlertDialog.Builder(context);
		popup.setCancelable(true);
		popup.setNegativeButton(R.string.close_dialog_button, new DialogInterface.OnClickListener() {
			
			public void onClick(DialogInterface view, int which) {
				if (which == DialogInterface.BUTTON_NEGATIVE)
					view.cancel();
			}
		});
		popup.setIcon(R.drawable.little_map_dude);
	}

	private Address getAddress(DeedLocation location) {
		Geocoder gc = new Geocoder(context, Locale.getDefault());
		Address address = null;
		try {
			List<Address> addresses = gc.getFromLocation(location.getLatitude(), location.getLongitude(), 1);
			if (addresses != null && addresses.size() > 0) {
				address = addresses.get(0);
			}
			return address;
		} catch (IOException e) {
			Log.v("MapItemView", e.getMessage());
			return address;
		}
	}

	private String getCity(Address address, String defaultValue) {
		String cityText = defaultValue;
		if (address != null) {
			String locality = address.getLocality();
			String country = address.getCountryName();
			cityText = formatCity(defaultValue, locality, country);
		}
		return cityText;
	}

	private String formatCity(String defaultValue, String locality, String country) {
		String cityText = null;
		if (locality != null && !("".equals(locality)))
			cityText = locality;
		if (country != null && !("".equals(country)))
			if (cityText == null)
				cityText = country;
			else
				cityText += ", " + country;
		if (cityText == null)
			cityText = defaultValue;
		return cityText;
	}

	private void showPopup(DeedLocation loc, String city) {
		popup.setTitle(loc.getDeedTitle());
		popup.setView(new MapItemView(context, loc, city));
		popup.show();
	}

	class GetCityAsyncTask extends AsyncTask<DeedLocation, Void, String> {
		DeedLocation loc;

		@Override
		protected String doInBackground(DeedLocation... locs) {
			if (locs != null && locs.length > 0) {
				loc = locs[0];
				Address address = getAddress(loc);
				return getCity(address, context.getString(R.string.good_deeds_title));
			}
			return null;
		}

		@Override
		protected void onPostExecute(String result) {
			showPopup(loc, result);
		}
	}
}
